package cn.sciento.boot.tenant.autoconfigure;

import cn.sciento.boot.tenant.aspect.aop.TenantCreateAdvice;
import cn.sciento.boot.tenant.aspect.aop.TenantCreateAdvisor;
import cn.sciento.boot.tenant.aspect.aop.TenantCreatePointcut;
import cn.sciento.boot.tenant.aspect.aop.TenantUpdateAdvice;
import cn.sciento.boot.tenant.aspect.aop.TenantUpdateAdvisor;
import cn.sciento.boot.tenant.aspect.aop.TenantUpdatePointcut;
import cn.sciento.boot.tenant.feign.HiamFeignService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@ComponentScans({@ComponentScan(basePackages = {"cn.sciento.boot.tenant"}), @ComponentScan({"cn.sciento.feign.extend"})})
@EnableFeignClients(basePackageClasses = {HiamFeignService.class})
@EnableAsync
@EnableAspectJAutoProxy
@EnableConfigurationProperties({TenantInitProperties.class})
public class TenantInitAutoConfiguration {
  @ConditionalOnProperty(prefix = "stong.tenant.init.aspect", name = {"enabled"}, havingValue = "true", matchIfMissing = false)
  static class Aspect {
    @Bean
    TenantCreateAdvisor tenantCreateAdvisor(TenantCreateAdvice tenantCreateAdvice, TenantCreatePointcut tenantCreatePointcut) {
      return new TenantCreateAdvisor(tenantCreateAdvice, tenantCreatePointcut);
    }
    
    @Bean
    TenantUpdateAdvisor tenantUpdateAdvisor(TenantUpdateAdvice tenantUpdateAdvice, TenantUpdatePointcut tenantUpdatePointcut) {
      return new TenantUpdateAdvisor(tenantUpdateAdvice, tenantUpdatePointcut);
    }
  }
  
  @Bean
  @Qualifier("tenantInitAsyncTaskExecutor")
  public AsyncTaskExecutor tenantInitAsyncTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("tenantInitAsyncTaskExecutor");
    executor.setMaxPoolSize(3);
    executor.setCorePoolSize(2);
    return executor;
  }
  
  @Bean
  @Qualifier("groupOrderlyAsyncTaskExecutor")
  public AsyncTaskExecutor groupOrderlyAsyncTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("groupOrderlyAsyncTaskExecutor");
    executor.setMaxPoolSize(3);
    executor.setCorePoolSize(2);
    return executor;
  }
  
  @Bean
  @Qualifier("groupWithoutOrderlyAsyncTaskExecutor")
  public AsyncTaskExecutor groupWithoutOrderlyAsyncTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("groupWithoutOrderlyAsyncTaskExecutor");
    executor.setMaxPoolSize(3);
    executor.setCorePoolSize(2);
    return executor;
  }
  
  @Bean
  @Qualifier("tenantInitLogAsyncTaskExecutor")
  public AsyncTaskExecutor tenantInitLogAsyncTaskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setThreadNamePrefix("tenantInitLogAsyncTaskExecutor");
    executor.setMaxPoolSize(3);
    executor.setCorePoolSize(2);
    return executor;
  }
}
